-
-
Notifications
You must be signed in to change notification settings - Fork 352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
review: fix replacing of field access by relaxed Parameter value contract #1476
Conversation
74b5ad6
to
5ed1f83
Compare
Travis CI is broken... |
5ed1f83
to
322b926
Compare
Thanks Pavel. |
This PR is alternative solution to #1444. The problems are described there. Short description: The proxy template parameter is needed not only in case of name conflict with existing field name, but is needed
Therefore I suggest to release the template parameter constraint you have introduced. It is the change introduced by this PR. |
322b926
to
19268f1
Compare
This reverts commit 7005aef.
19268f1
to
c4f033f
Compare
I see, I have to deeply understand the problem of #1444 then. However, I'm traveling, it may require some time I don't have yet. |
c4f033f
to
8aaeccb
Compare
Yes, the deeper understanding is needed. These are the concepts which have to be understood: C1) Template and SubstitutionVisitor are no more deeply bound together. The only binding is in constructor of SubstitutionVisitor, where Template is converted to C2) If the C3) If the These 3 concepts were origin target of the PR #1444. But then Simon came with interesting idea (commit Change SubstitutionVisitor to treat differently case A and case B) (if I understood him well) to make my solution more backward compatible.
Therefore I suggested to detect intention of the Template designer sooner - during extraction of It introduces concept C4) If the template parameter has a proxy name, then it is not substituted as String literal, but it is substituted in a simple name of the field/executable reference. Concept C4 can be used for field parameter in Template, but it cannot be used for field parameter in inner class (See TemplateTest#testFieldAccessNameSubstitutionInInnerClass) and it cannot be used for replacing of method invocation names (See TemplateTest#testTemplateInvocationSubstitution) Final I adapted the tests InvocationTemplate and FieldAccessOfInnerClassTemplate to use C4. I hope this PR is understandable now and we can continue here. |
I need C1, C2, C3. I base my templates on these rules. I am not sure concerning backward compatibility introduced by Simon and I am not sure whether C4 is the understandable solution. Do you see a better one? |
I like it as it is now. It is not compatible with some legacy templates, but it is more clear what template does. |
@@ -20,7 +20,7 @@ public TemplateWithFieldsAndMethods(String PARAM, | |||
} | |||
|
|||
public String methodToBeInserted() { | |||
return PARAM; | |||
return "PARAM"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one bothers me: one of the main interest of Spoon template, is that they are java typed. Here using return PARAM;
is right concerning the typing, but throws an exception as there's no field with the new name in the test.
With the proposed solution, (i.e. string parameters are used for renaming fields/methods), I don't think we can keep the typing safety for String (like here).
However we should provide an immediate feedback, when applying the template: I'd like to do it when a String parameter is used in this kind of case but it seems really complicated, maybe we can do it only when an error occured, instead of throwing an NPE, WDYT?
Good idea! I have added error handler which throws SpoonException instead of NPE + test of this situation. |
Nice job! It's far more clear like that for users I think. So, if I sum up String parameters are now used exclusively for replacing variable or method names, and we got a clear error if you use them to return a string for example. And if you want to use a parameter to return a string, you have to use a TemplateParameter or a CtLiteral, right? Then we are potentially breaking template clients here, but regarding all the bugs templates had we can assume that really few people used templates. I propose to conclude this PR that you update the javadoc of |
ok for me |
I believe that current implementation is better then before, but thinking about documenation, it looks it is not good intuitive/easily understandable. There is missing a concept, which would explicitly state the meaning of template String parameter. Whether The inconsistency / unfriendliness is that parameter of type int is automatically handled as int literal, while string is/was ambiguous - how to explain that in documentation? May be the solution would be, to introduce another annotation, which would explicitly express that parameter value is not a literal, but will be used as (part of the) simple name. Something like: @NameParameter(_name_)
String name; optional solution is to mark old templates as deprecated and to introduce template builder, which does not have this problem. |
I agree it was ambiguous but for me, String usage is now pretty clear: you use String type for a parameter only if you want to rename some element of the code. Else you use a CtLiteral. And we should document it like that.
It looks like a good idea indeed to use another annotation for stating that a parameter will be used only to rename code elements. I'm not sure about the usage of the argument inside the annotation: it should follow the same rule as standard parameter then. |
I would prefer to keep only one annotation for templates. So I would stick and merge this solution for now |
I agree. It is a good step in good direction. The template documentation should be updated too. But current examples with template parameter of type "int", which is automatically converted to CtLiteral is confusing if it will be extended with template parameter of type "String", which is NOT automatically converted to CtLiteral ... because of reasons we 3 understand, but which is hard to explain for me in documentation ... |
If you already started to change the documentation, push your changes, we'll be able to help you. In my point of view, we can keep things simple to explain the stuff around String parameters: String parameters are not working like other primitive type parameters, since we're using String parameters only to rename elements of the code like fields and methods. To use a parameter with a type String like other primitive types, use CtLiteral<String>. And give examples: anyway dev will only read the examples ;-) |
no, I did not. |
Please check the updated documentation and if it is OK, then this PR seems to be ready for merge. |
@pvojtechovsky I fixed the failing test case and I just updated the javadoc of |
@@ -70,7 +78,7 @@ | |||
* | |||
* <pre> | |||
* public class A { | |||
* public void insertedMethod() { | |||
* public void methodwithpPrameterizedName() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here is a typo mistake in method name.
It looks OK for me. Thank you for all your input and fixing documentation ;-) |
This is the alternative to the #1444 with